// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include <zencore/stats.h>
#include <zenhttp/auth/authmgr.h>
#include <zenhttp/httpserver.h>
#include <zenhttp/httpstats.h>
#include <zenstore/cidstore.h>

namespace zen {

class ProjectStore;

//////////////////////////////////////////////////////////////////////////
//
//  {project}	a project identifier
//  {target}	a variation of the project, typically a build target
//  {lsn}		oplog entry sequence number
//
//  /prj/{project}
//  /prj/{project}/oplog/{target}
//  /prj/{project}/oplog/{target}/{lsn}
//
// oplog entry
//
// id: {id}
// key: {}
// meta: {}
// data: []
// refs:
//

class HttpProjectService : public HttpService, public IHttpStatsProvider
{
public:
	HttpProjectService(CidStore& Store, ProjectStore* InProjectStore, HttpStatsService& StatsService, AuthMgr& AuthMgr);
	~HttpProjectService();

	virtual const char* BaseUri() const override;
	virtual void		HandleRequest(HttpServerRequest& Request) override;

	virtual void HandleStatsRequest(HttpServerRequest& Request) override;

private:
	struct ProjectStats
	{
		std::atomic_uint64_t ProjectReadCount{};
		std::atomic_uint64_t ProjectWriteCount{};
		std::atomic_uint64_t ProjectDeleteCount{};
		std::atomic_uint64_t OpLogReadCount{};
		std::atomic_uint64_t OpLogWriteCount{};
		std::atomic_uint64_t OpLogDeleteCount{};
		std::atomic_uint64_t OpHitCount{};
		std::atomic_uint64_t OpMissCount{};
		std::atomic_uint64_t OpWriteCount{};
		std::atomic_uint64_t ChunkHitCount{};
		std::atomic_uint64_t ChunkMissCount{};
		std::atomic_uint64_t ChunkWriteCount{};
		std::atomic_uint64_t RequestCount{};
		std::atomic_uint64_t BadRequestCount{};
	};

	void HandleProjectListRequest(HttpRouterRequest& Req);
	void HandleChunkBatchRequest(HttpRouterRequest& Req);
	void HandleFilesRequest(HttpRouterRequest& Req);
	void HandleChunkInfosRequest(HttpRouterRequest& Req);
	void HandleChunkInfoRequest(HttpRouterRequest& Req);
	void HandleChunkByIdRequest(HttpRouterRequest& Req);
	void HandleChunkByCidRequest(HttpRouterRequest& Req);
	void HandleOplogOpPrepRequest(HttpRouterRequest& Req);
	void HandleOplogOpNewRequest(HttpRouterRequest& Req);
	void HandleOpLogOpRequest(HttpRouterRequest& Req);
	void HandleOpLogRequest(HttpRouterRequest& Req);
	void HandleOpLogEntriesRequest(HttpRouterRequest& Req);
	void HandleProjectRequest(HttpRouterRequest& Req);
	void HandleOplogSaveRequest(HttpRouterRequest& Req);
	void HandleOplogLoadRequest(HttpRouterRequest& Req);
	void HandleRpcRequest(HttpRouterRequest& Req);
	void HandleDetailsRequest(HttpRouterRequest& Req);
	void HandleProjectDetailsRequest(HttpRouterRequest& Req);
	void HandleOplogDetailsRequest(HttpRouterRequest& Req);
	void HandleOplogOpDetailsRequest(HttpRouterRequest& Req);

	inline LoggerRef Log() { return m_Log; }

	LoggerRef				 m_Log;
	CidStore&				 m_CidStore;
	HttpRequestRouter		 m_Router;
	Ref<ProjectStore>		 m_ProjectStore;
	HttpStatsService&		 m_StatsService;
	AuthMgr&				 m_AuthMgr;
	ProjectStats			 m_ProjectStats;
	metrics::OperationTiming m_HttpRequests;
};

}  // namespace zen
